package com.xuecheng.media.controller;


import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.vod.model.v20170321.CreateUploadVideoResponse;
import com.aliyuncs.vod.model.v20170321.RefreshUploadVideoResponse;
import com.xuecheng.api.media.model.AliyunVodApi;
import com.xuecheng.api.media.model.aliyun.VodUploadRequest;
import com.xuecheng.api.media.model.aliyun.VodUploadToken;
import com.xuecheng.media.common.utils.AliyunVODUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
public class AliyunVodController implements AliyunVodApi {

    /*
   aliyun.region = cn-shanghai
aliyun.accessKeyId = LTAI5t5sGv2CcQt8ikiGfeJ8
aliyun.accessKeySecret = uSfkfi27oMNiPf2sW4jwOonbmSBLO4
    */
    @Value("${aliyun.region}")
    private String region;
    @Value("${aliyun.accessKeyId}")
    private String accessKeyId;
    @Value("${aliyun.accessKeySecret}")
    private String accessKeySecret;
    //上传凭证获取
    @PostMapping("media/vod-token")
    public VodUploadToken generateUploadToken(@RequestBody VodUploadRequest request) {
        VodUploadToken token = null;
        /*todo
             解析:
                 因为这里使用阿里云是外部服务  只要是访问外部服务有异常必须使用  try ,catch 进行捕获  ,不能抛
                 原因 : 网络(网络抖动: 1连接超时 2连接失败)
                 外部的错误一定要日志进行记录和返回默认的错误信息
                 另外 使用try --catch灵活性非常高
         */
        try {
            // 1.获得client对象,client对象是阿里云的客户端对象
            DefaultAcsClient client = AliyunVODUtil.initVodClient(region, accessKeyId, accessKeySecret);
            //2获取响应对象
            CreateUploadVideoResponse response = AliyunVODUtil.createUploadVideo(client, request.getTitle(), request.getFileName());
            // 3.解析数据并封装结果
            //3.1 视频上传凭证封装对象
            token = new VodUploadToken();
            token.setVideoId(response.getVideoId());
            token.setUploadAuth(response.getUploadAuth());
            token.setUploadAddress(response.getUploadAddress());
            token.setRequestId(response.getRequestId());
            return token;
        } catch (Exception e) {
            //e.printStackTrace();  todo   注意开发中绝对不可以这样书写   下面解析
            /*todo
               e.printStackTrace();  不能书写的原因   并且会把所有的错误打印出来
                    如果业务出错,请求量很大.直接导致服务器宕机   :就是io阻塞
                      说白了就是堆栈错误  ,堆栈满了
                      举例说明 就像弹夹一样,不停压入子弹(不停请求),
                      但是由于无法打出(由于业务错误无法响应),栈就会满掉,从而造成宕机,就是io阻塞
             */
            // 处理方式:
            //第一种:  返回默认数据并记录错误信息(本项目)
            log.error("阿里云视频上传凭证获取错误" + e.getMessage()); //e.getMessage只会获得提什么异常,并不会和上面一样打印出所有异常信息
            token = new VodUploadToken();
            /*第二种:  记录错误信息,并将异常向外抛
            log.error("阿里云视频上传凭证获取错误" + e.getMessage()); //e.getMessage只会获得提什么异常,并不会和上面一样打印出所有异常信息
            ExceptionCast.cast(MediaErrorCode.E_140012);
*/
            return token;
        }

    }
    //上传凭证刷新
    @GetMapping("media/refresh-vod-token/{videoId}")
    public VodUploadToken refreshUploadToken(String videoId) {
        VodUploadToken token = null;
        try {
            // 1.获得client对象
            DefaultAcsClient client = AliyunVODUtil.initVodClient(region, accessKeyId, accessKeySecret);

            // 2.获得response对象
            RefreshUploadVideoResponse response = AliyunVODUtil.refreshUploadVideo(client, videoId);

            // 3.解析数据并封装结果
            token = new VodUploadToken();
            token.setVideoId(response.getVideoId());
            token.setUploadAuth(response.getUploadAuth());
            token.setUploadAddress(response.getUploadAddress());
            token.setRequestId(response.getRequestId());

            return token;
        } catch (Exception e) {

            //e.printStackTrace();  如果业务出错，并且请求量很大，直接导致服务器宕机：io阻塞

            // 处理的手段：1.返回默认数据并记录错误信息（本项目）   2.记录错误信息，并将异常向外抛出

            log.error("获得阿里云上传文件凭证失败：{}",e.getMessage());
            token = new VodUploadToken();

            // 将系统异常转为业务异常
            // log.error("获得阿里云上传文件凭证失败：{}",e.getMessage());
            // ExceptionCast.cast(MediaErrorCode.E_140012);

            return token;
        }
    }
}